package org.springframework.boot.netty.support;

import io.netty.buffer.ByteBuf;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.multipart.DefaultHttpDataFactory;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import io.netty.handler.codec.http.multipart.InterfaceHttpData;
import io.netty.handler.codec.http.multipart.MemoryAttribute;
import org.springframework.util.StringUtils;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Author: huoxingzhi
 * Date: 2020/12/25
 * Email: hxz_798561819@163.com
 */
public class HttpParamParser {

    public static Map<String,String> parseHeaders(FullHttpRequest fullHttpRequest){
        Map<String,String> headersMap = new HashMap<>();
        // 解析http header 信息
        HttpHeaders headers = fullHttpRequest.headers();
        headers.entries().forEach(header ->{
            headersMap.put(header.getKey(),header.getValue());
        });
        return headersMap;
    }

    public static Map<String, Object> parseParams(FullHttpRequest fullHttpRequest){
        if (fullHttpRequest.method() == HttpMethod.GET) {
            return parseGetParams(fullHttpRequest);
        }

        if (fullHttpRequest.method() == HttpMethod.POST) {
            return parsePostParams(fullHttpRequest);
        }

        return null;
    }

    private static Map<String, Object> parseGetParams(FullHttpRequest fullHttpRequest) {
        Map<String, Object> params = new HashMap<String, Object>();
        String strContentType = fullHttpRequest.headers().get("Content-type");
        if (!StringUtils.hasLength(strContentType)){
            strContentType = "text/html";
        }
        if ( strContentType.contains("application/json")) {
            try {
                params = getJSONParams(fullHttpRequest);
            } catch (UnsupportedEncodingException e) {
                return null;
            }
        } else {
            QueryStringDecoder decoder = new QueryStringDecoder(fullHttpRequest.uri());
            Map<String, List<String>> paramList = decoder.parameters();
            for (Map.Entry<String, List<String>> entry : paramList.entrySet()) {
                if (entry.getValue().size() > 1) {
                    params.put(entry.getKey(), entry.getValue());
                } else {
                    params.put(entry.getKey(), entry.getValue().get(0));
                }
            }
        }
        return params;

    }

    private static Map<String, Object> parsePostParams(FullHttpRequest fullHttpRequest) {
        Map<String, Object> params = new HashMap<String, Object>();
        String strContentType = fullHttpRequest.headers().get("Content-type").trim();
//            if (strContentType.contains("x-www-form-urlencoded")) {
        if (strContentType.contains("form")) {
            params = getFormParams(fullHttpRequest);
        } else if (strContentType.contains("application/json")) {
            try {
                params = getJSONParams(fullHttpRequest);
            } catch (UnsupportedEncodingException e) {
                return null;
            }
        } else {
            return null;
        }
        return params;
    }

    private static Map<String, Object> getFormParams(FullHttpRequest fullHttpRequest) {
        Map<String, Object> params = new HashMap<String, Object>();
        // HttpPostMultipartRequestDecoder
        HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(new DefaultHttpDataFactory(false), fullHttpRequest);
        List<InterfaceHttpData> postData = decoder.getBodyHttpDatas();
        for (InterfaceHttpData data : postData) {
            if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.Attribute) {
                MemoryAttribute attribute = (MemoryAttribute) data;
                params.put(attribute.getName(), attribute.getValue());
            }
        }
        return params;
    }

    private static Map<String, Object> getJSONParams(FullHttpRequest fullHttpRequest) throws UnsupportedEncodingException {
        Map<String, Object> params = new HashMap<String, Object>();
        ByteBuf content = fullHttpRequest.content();
        byte[] reqContent = new byte[content.readableBytes()];
        content.readBytes(reqContent);
        String strContent = new String(reqContent, "UTF-8");
      /*  JSONObject jsonObject = JSONObject.parseObject(strContent);
        for (String key : jsonObject.keySet()) {
            params.put(key, jsonObject.get(key));
        }*/
        params = JsonUtil.string2Map(strContent);
        return params;
    }


}
